package com.ybg.block.core.eth.remoteapi;

import com.ybg.block.core.dbapi.entity.BlockWalletAccount;
import com.ybg.block.core.dbapi.service.BlockWalletAccountService;
import com.ybg.framework.vo.R;
import com.ybg.share.core.enums.WalletType;
import com.ybg.share.core.eth.EthAccountRemoteApi;
import com.ybg.share.core.eth.dto.EthTransactionDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.admin.Admin;
import org.web3j.protocol.core.methods.request.Transaction;

import java.io.IOException;
import java.math.BigInteger;
import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Service(version = "${dubbo.provider.version}", timeout = 120000, cache = "false")
public class EthAccountRemoteApiImpl implements EthAccountRemoteApi {

    @Autowired
    Admin admin;
    @Autowired
    Web3j web3j;
    @Autowired
    BlockWalletAccountService walletAccountService;

    @Override
    public R<List<String>> getAccounts() {
        try {
            return R.success(admin.personalListAccounts().send().getAccountIds());
        } catch (Exception e) {
            log.error("{}", e);
        }
        return R.success(null);
    }

    @Override
    public R<String> addAccount(String password) {
        try {
            String accountId = admin.personalNewAccount(password).send().getResult();
            BlockWalletAccount account = new BlockWalletAccount();
            account.setAccount(accountId);
            account.setCreateTime(LocalDateTime.now());
            account.setWalletType(WalletType.ETH.getValue());
            account.setPassword(password);
            walletAccountService.save(account);
            return R.success(accountId);
        } catch (Exception e) {
            log.error("{}", e);
            return R.fail("创建失败");
        }
    }

    @Override
    public R<Boolean> unlockAccount(String account, String passphrase) {

        try {
            Boolean result = admin.personalUnlockAccount(account, passphrase).send().accountUnlocked();
            return R.success(result);
        } catch (IOException e) {
            e.printStackTrace();
            return R.fail("执行失败");
        }
    }

    @Override
    public R<String> send(String password, EthTransactionDTO dto) {
        //String from, BigInteger nonce, BigInteger gasPrice, String init
        String from = dto.getFrom();
        BigInteger nonce = dto.getNonce();
        BigInteger gasPrice = dto.getGasPrice();
        BigInteger gasLimit = dto.getGasLimit();
        String to = dto.getTo();
        BigInteger value = dto.getValue();
        String data = dto.getData();
        Transaction transaction = new Transaction(from, nonce, gasPrice, gasLimit, to, value, data);
        try {
            //调用可以在一次调用中完成交易的签名和发送。 执行此交易的账户无需解锁，执行后也不会处于解锁状态。
            //调用返回32字节长的交易哈希字符串，或者当交易无效时 返回零哈希
            String hash = admin.personalSendTransaction(transaction, password).send().getTransactionHash();
            log.info(hash);
            return R.success(hash);
        } catch (IOException e) {
//            e.printStackTrace();
            log.error("{}", e);
            return R.fail("执行失败");
        }

    }


}
